<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" type="text/css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css">
    <link rel="stylesheet" href="./resources/prism/prism.css" type="text/css">
    <link rel="stylesheet" href="../css/ol.css" type="text/css">
    <link rel="stylesheet" href="./resources/layout.css" type="text/css">
    
    
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="./resources/zeroclipboard/ZeroClipboard.min.js"></script>
    <title>Hit Tolerance</title>
  </head>
  <body>

    <header class="navbar" role="navigation">
      <div class="container">
        <div class="display-table pull-left" id="navbar-logo-container">
          <a class="navbar-brand" href="./"><img src="./resources/logo-70x70.png">&nbsp;OpenLayers Examples</a>
        </div>
        <!-- menu items that get hidden below 768px width -->
        <nav class='collapse navbar-collapse navbar-responsive-collapse'>
          <ul class="nav navbar-nav pull-right">
            <li><a href="../doc">Docs</a></li>
            <li><a class="active" href="index.html">Examples</a></li>
            <li><a href="../apidoc">API</a></li>
            <li><a href="https://github.com/openlayers/openlayers">Code</a></li>
          </ul>
        </nav>
      </div>
    </header>

    <div class="container-fluid">

      <div id="latest-check" class="alert alert-warning alert-dismissible" role="alert" style="display:none">
        <button id="latest-dismiss" type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        This example uses OpenLayers v<span>4.4.2</span>. The <a id="latest-link" href="#" class="alert-link">latest</a> is v<span id="latest-version"></span>.
      </div>

      <div class="row-fluid">
        <div class="span12">
          <h4 id="title">Hit Tolerance</h4>
          <div id="map" class="map"></div>
<form class="form-inline">
  <span id="status">&nbsp;No feature got hit.</span>
  <br />
  <label>Hit tolerance for selecting features </label>
  <select id="hitTolerance" class="form-control">
    <option value="0" selected>0 Pixels</option>
    <option value="5">5 Pixels</option>
    <option value="10">10 Pixels</option>
  </select>
  <br />
  Area: &nbsp;<canvas id="circle" style="vertical-align: middle"/>
</form>

        </div>
      </div>

      <div class="row-fluid">
        <div class="span12">
          <p id="shortdesc">Example using the hitTolerance parameter.</p>
          <div id="docs"><p>By default, the map.forEachFeatureAtPixel() function only considers features that are directly under the provided pixel. This can make it difficult to interact with features on touch devices. To consider features within some distance of the provided pixel, use the hitTolerance option. For example, map.forEachFeatureAtPixel(pixel, callback, {hitTolerance: 3}) will call the callback with all features that are within three pixels of the provided pixel.</p>
</div>
          <div id="api-links">Related API documentation: <ul class="inline"><li><a href="../apidoc/ol.Map.html" title="API documentation for ol.Map">ol.Map</a></li>,<li><a href="../apidoc/ol.View.html" title="API documentation for ol.View">ol.View</a></li>,<li><a href="../apidoc/ol.layer.Tile.html" title="API documentation for ol.layer.Tile">ol.layer.Tile</a></li>,<li><a href="../apidoc/ol.layer.Vector.html" title="API documentation for ol.layer.Vector">ol.layer.Vector</a></li>,<li><a href="../apidoc/ol.source.OSM.html" title="API documentation for ol.source.OSM">ol.source.OSM</a></li>,<li><a href="../apidoc/ol.source.Vector.html" title="API documentation for ol.source.Vector">ol.source.Vector</a></li>,<li><a href="../apidoc/ol.Feature.html" title="API documentation for ol.Feature">ol.Feature</a></li>,<li><a href="../apidoc/ol.geom.LineString.html" title="API documentation for ol.geom.LineString">ol.geom.LineString</a></li>,<li><a href="../apidoc/ol.style.Style.html" title="API documentation for ol.style.Style">ol.style.Style</a></li>,<li><a href="../apidoc/ol.style.Stroke.html" title="API documentation for ol.style.Stroke">ol.style.Stroke</a></li></ul></div>
        </div>
      </div>

      <div class="row-fluid">
        <div id="source-controls">
          <a id="copy-button"><i class="fa fa-clipboard"></i> Copy</a>
          <a id="codepen-button"><i class="fa fa-codepen"></i> Edit</a>
        </div>
        <form method="POST" id="codepen-form" target="_blank" action="https://codepen.io/pen/define/">
          <textarea class="hidden" name="title">Hit Tolerance</textarea>
          <textarea class="hidden" name="description">Example using the hitTolerance parameter.</textarea>
          <textarea class="hidden" name="js">var raster &#x3D; new ol.layer.Tile({
  source: new ol.source.OSM()
});

var style &#x3D; new ol.style.Style({
  stroke: new ol.style.Stroke({
    color: &#x27;black&#x27;,
    width: 1
  })
});

var feature &#x3D; new ol.Feature(new ol.geom.LineString([[-4000000, 0], [4000000, 0]]));

var vector &#x3D; new ol.layer.Vector({
  source: new ol.source.Vector({
    features: [feature]
  }),
  style: style
});

var map &#x3D; new ol.Map({
  layers: [raster, vector],
  target: &#x27;map&#x27;,
  view: new ol.View({
    center: [0, 0],
    zoom: 2
  })
});

var hitTolerance;

var statusElement &#x3D; document.getElementById(&#x27;status&#x27;);

map.on(&#x27;singleclick&#x27;, function(e) {
  var hit &#x3D; false;
  map.forEachFeatureAtPixel(e.pixel, function() {
    hit &#x3D; true;
  }, {
    hitTolerance: hitTolerance
  });
  if (hit) {
    style.getStroke().setColor(&#x27;green&#x27;);
    statusElement.innerHTML &#x3D; &#x27;&amp;nbsp;A feature got hit!&#x27;;
  } else {
    style.getStroke().setColor(&#x27;black&#x27;);
    statusElement.innerHTML &#x3D; &#x27;&amp;nbsp;No feature got hit.&#x27;;
  }
  feature.changed();
});

var selectHitToleranceElement &#x3D; document.getElementById(&#x27;hitTolerance&#x27;);
var circleCanvas &#x3D; document.getElementById(&#x27;circle&#x27;);

var changeHitTolerance &#x3D; function() {
  hitTolerance &#x3D; parseInt(selectHitToleranceElement.value, 10);

  var size &#x3D; 2 * hitTolerance + 2;
  circleCanvas.width &#x3D; size;
  circleCanvas.height &#x3D; size;
  var ctx &#x3D; circleCanvas.getContext(&#x27;2d&#x27;);
  ctx.clearRect(0, 0, size, size);
  ctx.beginPath();
  ctx.arc(hitTolerance + 1, hitTolerance + 1, hitTolerance + 0.5, 0, 2 * Math.PI);
  ctx.fill();
  ctx.stroke();
};

selectHitToleranceElement.onchange &#x3D; changeHitTolerance;
changeHitTolerance();
</textarea>
          <textarea class="hidden" name="css"></textarea>
          <textarea class="hidden" name="html">&lt;div id&#x3D;&quot;map&quot; class&#x3D;&quot;map&quot;&gt;&lt;/div&gt;
&lt;form class&#x3D;&quot;form-inline&quot;&gt;
  &lt;span id&#x3D;&quot;status&quot;&gt;&amp;nbsp;No feature got hit.&lt;/span&gt;
  &lt;br /&gt;
  &lt;label&gt;Hit tolerance for selecting features &lt;/label&gt;
  &lt;select id&#x3D;&quot;hitTolerance&quot; class&#x3D;&quot;form-control&quot;&gt;
    &lt;option value&#x3D;&quot;0&quot; selected&gt;0 Pixels&lt;/option&gt;
    &lt;option value&#x3D;&quot;5&quot;&gt;5 Pixels&lt;/option&gt;
    &lt;option value&#x3D;&quot;10&quot;&gt;10 Pixels&lt;/option&gt;
  &lt;/select&gt;
  &lt;br /&gt;
  Area: &amp;nbsp;&lt;canvas id&#x3D;&quot;circle&quot; style&#x3D;&quot;vertical-align: middle&quot;/&gt;
&lt;/form&gt;
</textarea>
          <input type="hidden" name="resources" value="https://openlayers.org/en/v4.4.2/css/ol.css,https://openlayers.org/en/v4.4.2/build/ol.js">
          <input type="hidden" name="data">
        </form>
        <pre><code id="example-source" class="language-markup">&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Hit Tolerance&lt;/title&gt;
    &lt;link rel="stylesheet" href="https://openlayers.org/en/v4.4.2/css/ol.css" type="text/css"&gt;
    &lt;!-- The line below is only needed for old environments like Internet Explorer and Android 4.x --&gt;
    &lt;script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"&gt;&lt;/script&gt;
    &lt;script src="https://openlayers.org/en/v4.4.2/build/ol.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id&#x3D;&quot;map&quot; class&#x3D;&quot;map&quot;&gt;&lt;/div&gt;
    &lt;form class&#x3D;&quot;form-inline&quot;&gt;
      &lt;span id&#x3D;&quot;status&quot;&gt;&amp;nbsp;No feature got hit.&lt;/span&gt;
      &lt;br /&gt;
      &lt;label&gt;Hit tolerance for selecting features &lt;/label&gt;
      &lt;select id&#x3D;&quot;hitTolerance&quot; class&#x3D;&quot;form-control&quot;&gt;
        &lt;option value&#x3D;&quot;0&quot; selected&gt;0 Pixels&lt;/option&gt;
        &lt;option value&#x3D;&quot;5&quot;&gt;5 Pixels&lt;/option&gt;
        &lt;option value&#x3D;&quot;10&quot;&gt;10 Pixels&lt;/option&gt;
      &lt;/select&gt;
      &lt;br /&gt;
      Area: &amp;nbsp;&lt;canvas id&#x3D;&quot;circle&quot; style&#x3D;&quot;vertical-align: middle&quot;/&gt;
    &lt;/form&gt;
    &lt;script&gt;
      var raster &#x3D; new ol.layer.Tile({
        source: new ol.source.OSM()
      });

      var style &#x3D; new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: &#x27;black&#x27;,
          width: 1
        })
      });

      var feature &#x3D; new ol.Feature(new ol.geom.LineString([[-4000000, 0], [4000000, 0]]));

      var vector &#x3D; new ol.layer.Vector({
        source: new ol.source.Vector({
          features: [feature]
        }),
        style: style
      });

      var map &#x3D; new ol.Map({
        layers: [raster, vector],
        target: &#x27;map&#x27;,
        view: new ol.View({
          center: [0, 0],
          zoom: 2
        })
      });

      var hitTolerance;

      var statusElement &#x3D; document.getElementById(&#x27;status&#x27;);

      map.on(&#x27;singleclick&#x27;, function(e) {
        var hit &#x3D; false;
        map.forEachFeatureAtPixel(e.pixel, function() {
          hit &#x3D; true;
        }, {
          hitTolerance: hitTolerance
        });
        if (hit) {
          style.getStroke().setColor(&#x27;green&#x27;);
          statusElement.innerHTML &#x3D; &#x27;&amp;nbsp;A feature got hit!&#x27;;
        } else {
          style.getStroke().setColor(&#x27;black&#x27;);
          statusElement.innerHTML &#x3D; &#x27;&amp;nbsp;No feature got hit.&#x27;;
        }
        feature.changed();
      });

      var selectHitToleranceElement &#x3D; document.getElementById(&#x27;hitTolerance&#x27;);
      var circleCanvas &#x3D; document.getElementById(&#x27;circle&#x27;);

      var changeHitTolerance &#x3D; function() {
        hitTolerance &#x3D; parseInt(selectHitToleranceElement.value, 10);

        var size &#x3D; 2 * hitTolerance + 2;
        circleCanvas.width &#x3D; size;
        circleCanvas.height &#x3D; size;
        var ctx &#x3D; circleCanvas.getContext(&#x27;2d&#x27;);
        ctx.clearRect(0, 0, size, size);
        ctx.beginPath();
        ctx.arc(hitTolerance + 1, hitTolerance + 1, hitTolerance + 0.5, 0, 2 * Math.PI);
        ctx.fill();
        ctx.stroke();
      };

      selectHitToleranceElement.onchange &#x3D; changeHitTolerance;
      changeHitTolerance();
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
      </div>
    </div>

    <script src="./resources/common.js"></script>
    <script src="./resources/prism/prism.min.js"></script>
    <script src="loader.js?id=hit-tolerance"></script>
  </body>
  <script>
  var packageUrl = 'https://raw.githubusercontent.com/openlayers/openlayers.github.io/build/package.json';
  fetch(packageUrl).then(function(response) {
    return response.json();
  }).then(function(json) {
    var latestVersion = json.version;
    document.getElementById('latest-version').innerHTML = latestVersion;
    var url = window.location.href;
    var branchSearch = url.match(/\/([^\/]*)\/examples\//);
    var cookieText = 'dismissed=-' + latestVersion + '-';
    var dismissed = document.cookie.indexOf(cookieText) != -1;
    if (!dismissed && /^v[0-9\.]*$/.test(branchSearch[1]) && '4.4.2' != latestVersion) {
      var link = url.replace(branchSearch[0], '/latest/examples/');
      fetch(link, {method: 'head'}).then(function(response) {
        var a = document.getElementById('latest-link');
        a.href = response.status == 200 ? link : '../../latest/examples/';
      });
      var latestCheck = document.getElementById('latest-check');
      latestCheck.style.display = '';
      document.getElementById('latest-dismiss').onclick = function() {
        latestCheck.style.display = 'none';
        document.cookie = cookieText;
      }
    }
  });
  </script>
</html>
